<?php
// $Id$
/**
 * This file contains {@link VetoableEventListener} which is part of the PHP 
 * Content Repository (phpCR), a derivative of the Java Content Repository 
 * JSR-170, and is licensed under the Apache License, Version 2.0.
 *
 * This file is based on the code created for
 * {@link http://www.jcp.org/en/jsr/detail?id=170 JSR-170}
 *
 * @author Travis Swicegood <travis@domain51.net>
 * @copyright PHP Code Copyright &copy; 2004-2005, Domain51, United States
 * @copyright Original Java and Documentation 
 *  Copyright &copy; 2002-2004, Day Management AG, Switerland
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, 
 *      Version 2.0
 * @package phpContentRepository
 * @subpackage Level2
 */

/**
 * Load the {@link phpCR} library file(s)
 */ 
require_once(dirname(__FILE__) . '/../phpCR.library.php');


/**
 * The possible actions specified by the {@link onParentVersion} attribute
 * in a {@link Property} definition within a {@link Node} type definition.
 *
 * Level 2 only
 *
 * This interface defines the following actions:
 * <ul>
 *    <li>{@link COPY}</li>
 *    <li>{@link VERSION}</li>
 *    <li>{@link INITIALIZE}</li>
 *    <li>{@link COMPUTE}</li>
 *    <li>{@link IGNORE}</li>
 *    <li>{@link ABORT}</li>
 * </ul>
 *
 * Every {@link Item} ({@link Node} or {@link Property}) in the repository has 
 * a status indicator that governs what happens to that {@link Item} when its 
 * parent {@link Node} is versioned. This status is defined by the 
 * onParentVersion attribute in the {@link PropertyDef} or {@link NodeDef} that
 * applies to the {@link Item} in question. This {@link PropertyDef} or 
 * {@link NodeDef} is part of the {@link NodeType} of the parent {@link Node}
 * of the {@link Item} in question.
 *
 * For example, let N be a versionable {@link Node} in {@link Workspace} W of 
 * repository R.  Furthermore, let N be of {@link NodeType} T, where T is a
 * sub-type of nt:versionable and T allows N to have one {@link Property} called
 * P and one child {@link Node} called C.
 *
 * What happens to P and C when N is versioned depends on their respective 
 * OnParentVersion attribute as defined in the {@link PropertyDef} for P and 
 * the {@link NodeDef} for C, found in the definition of {@link NodeType} T.
 *
 * The possible values for the OnParentVersion attribute are: {@link COPY},
 * {@link VERSION}, {@link INITIALIZE}, {@link COMPUTE}, {@link NOTHING} and 
 * {@link FORBIDDEN}.
 *
 * The sections below describe, for each possible value of the OnParentVersion
 * attribute, what happens to C and P when:
 *
 * <ul>
 *      <li>N->checkin() is performed, creating the new version VN and adding
 *          to the version history.</li>
 *      <li>N->restore(VN) is performed, restoring the version VN.</li>
 * </ul>
 *
 *      

 * @author PHP - Travis Swicegood <travis@domain51.net>
 * @copyright Copyright &copy; 2004-2005, Domain51
 * @package phpContentRepository
 * @subpackage Level2
 */
class OnParentVersionAction 
{

   /**
    * Defines the integer value of a COPY action for a parent versioning event.
    *
    * See {@link OnParentVersion} for a full explanation of the scenario under
    * which these two events could possibly play out.
    *
    * Child {@link Node}
    * 
    * On checkin of N, C and all its descendent {@link Item}s, down to the 
    * leaves of the subtree, will be copied to the version storage as a child
    * subtree of VN. The copy of C and its subtree will not have its own 
    * version history but will be part of the state preserved in VN.  C itself
    * need not be versionable.
    *
    * On restore of VN, the copy of C and its subtree stored will be restored 
    * as well, replacing the current C and its subtree in the {@link Workspace}.
    * 
    * {@link Property}
    *
    * On checkin of N, P will be copied to the version storage as a child of VN.
    * This copy of P is part of the state preserved in VN.
    * 
    * On restore of VN, the copy of P stored as its child will be restored as 
    * well, replacing the current P in the {@link Workspace}.
    *
    * @var int
    * @see ACTIONNAME_COPY
    */
    const COPY = 1;
    
    
   /**
    * Defines the integer value of a VERSION action for a parent versioning 
    * event.
    *
    * See {@link OnParentVersion} for a full explanation of the scenario under
    * which these two events could possibly play out.
    *
    * Child {@link Node}
    * 
    * On checkin of N, the {@link Node} VN will get a child reference to the 
    * version history of C (not to C or any actual version of C). In practice, 
    * this means that the root version of C's version history becomes the 
    * child of VN because, as mentioned before, the root version is used as the 
    * referent when a reference to the version history as a whole is required. 
    * This also requires that C itself be versionable (otherwise it would not 
    * have a version history). If C is not versionable then behavior of IGNORE 
    * applies on checkin (see below).
    * 
    * On restore of VN, if the {@link Workspace} currently has an already 
    * existing {@link Node} corresponding to C's version history, then that 
    * instance of C becomes the child of the restored N. If the 
    * {@link Workspace} does not have an instance of C then one is restored 
    * from C's version history. The {@link Workspace} in which the restore is 
    * being performed will determine which particular version of C will be
    * restored. This determination depends on the configuration of the 
    * {@link Workspace} and is outside the scope of this specification.
    * 
    * {@link Property}
    * 
    * In the case of {@link Property}s, an OnParentVersion attribute of VERSION
    * has the same effect as COPY.
    *
    * @var int
    * @see ACTIONNAME_VERSION
    */
    const VERSION = 2;
    
    
   /**
    * Defines the integer value of a INITIALIZE action for a parent versioning 
    * event.
    *
    * See {@link OnParentVersion} for a full explanation of the scenario under
    * which these two events could possibly play out.
    * 
    * Child {@link Node}
    * 
    * On checkin of N, a new {@link Node} C will be created and placed in 
    * version storage as a child of VN.  This new C will be initialized just as 
    * it would be if created normally in a {@link Workspace}. No state 
    * information of the current C in the {@link Workspace} is preserved. The 
    * new C will not have its own version history but will be part of the state 
    * preserved in VN. C itself need not be versionable.
    *
    * On restore of VN, the C stored as its child will be restored as well, 
    * replacing the current C in the {@link Workspace}.
    * 
    * {@link Property}
    *
    * On checkin of N, a new P will be created and placed in version storage 
    * as a child of VN. The new P will be initialized just as it would be if
    * created normally in a {@link Workspace}. The new P is part of the state
    * preserved in VN. 
    * 
    * On restore of VN, the P stored as its child will be restored as well, 
    * replacing the current P in the {@link Workspace}.
    *
    * @var int
    * @see ACTIONNAME_INITIALIZE
    */
    const INITIALIZE = 3;
    
    
   /**
    * Defines the integer value of a COMPUTE action for a parent versioning 
    * event.
    *
    * See {@link OnParentVersion} for a full explanation of the scenario under
    * which these two events could possibly play out.
    *
    * Child {@link Node}
    * 
    * On checkin of N, a new {@link Node} C will be created and placed in 
    * version storage as a child of VN.  This new C will be initialized 
    * according to some configuration-specific procedure beyond the scope of 
    * this specification. The new C will not have its own version history but 
    * will be part of the state preserved in VN.  C itself need not be 
    * versionable.
    * 
    * On restore of VN, the C stored as its child will be restored as well, 
    * replacing the current C in the {@link Workspace}.
    * 
    * {@link Property}
    * 
    * On checkin of N, a new P will be created and placed in version storage as
    * a child of VN. The new P will be initialized according to some 
    * configuration-specific procedure beyond the scope of this specification. 
    * The new P is part of the state preserved in VN.
    * 
    * On restore of VN, the P stored as its child will be restored as well,
    * replacing the current P in the {@link Workspace}.
    */
    const COMPUTE = 4;
    
    
   /**
    * Defines the integer value of a IGNORE action for a parent versioning 
    * event.
    *
    * Child {@link Node}
    * 
    * On checkin of N, no state information about C will be stored in VN. 
    * 
    * On restore of VN, the child {@link Node} C of the current N will remain 
    * and not be removed, despite not being included in the state recorded in 
    * VN, since its IGNORE status tells the system to leave it alone.
    * 
    * {@link Property}
    * 
    * On checkin of N, no state information about P will be stored in VN.
    * 
    * On restore of VN, the {@link Property} P of the current N will remain and 
    * not be removed, despite not being included in the state of recorded in 
    * VN, since its IGNORE status tells the system to leave it alone.
    *
    * @var int
    * @see ACTIONNAME_IGNORE
    */
    const IGNORE = 5;
    
    
   /**
    * Defines the integer value of a ABORT action for a parent versioning 
    * event.
    *
    * See {@link OnParentVersion} for a full explanation of the scenario under
    * which these two events could possibly play out.
    *
    * Child {@link Node} or {@link Property}
    * 
    * On checkin of N an exception will be thrown. Having a child {@link Node}
    * or {@link Property} with an OnParentVersion attribute of 
    * {@link OnParentVersion::ABORT} prevents the parent {@link Node} from
    * being checked-in.
    *
    * @var int
    * @see ACTIONNAME_ABORT
    */
    const ABORT = 6;
    
    
   /**
    * The plain-text name of {@link COPY}
    *
    * @var string
    * @see COPY
    */
    const ACTIONNAME_COPY = "COPY";
    
    
   /**
    * The plain-text name of {@link VERSION}
    *
    * @var string
    * @see VERSION
    */
    const ACTIONNAME_VERSION = "VERSION";
    
    
   /**
    * The plain-text name of {@link INITIALIZE}
    *
    * @var string
    * @see INITIALIZE
    */
    const ACTIONNAME_INITIALIZE = "INITIALIZE";
    
    
   /**
    * The plain-text name of {@link COMPUTE}
    *
    * @var string
    * @see COMPUTE
    */
    const ACTIONNAME_COMPUTE = "COMPUTE";
    
    
   /**
    * The plain-text name of {@link IGNORE}
    *
    * @var string
    * @see IGNORE
    */
    const ACTIONNAME_IGNORE = "IGNORE";
    
    
   /**
    * The plain-text name of {@link ABORT}
    *
    * @var string
    * @see ABORT
    */
    const ACTIONNAME_ABORT = "ABORT";
    
    
   /**
    * Private constructor to prevent instantiation 
    */
    private final function __construct()
    {
        
    }
    

   /**
    * Returns the name of the specified $action, as used in serialization.
    *
    * @param int
    *   The on-version action.  See class constants.
    * @return string
    *   The name of the specified $action
    *
    * @throws {@link IllegalArgumentException}
    *   If $action is not a valid on-version action.
    */
    static public function nameFromValue($action) 
    {
        assert('is_int($action)');
        
        switch ($action) {
        case self::COPY:
            return self::ACTIONNAME_COPY;
            break;
   
        case self::VERSION:
            return self::ACTIONNAME_VERSION;
            break;
   
        case self::INITIALIZE:
	        return self::ACTIONNAME_INITIALIZE;
            break;
   
        case self::COMPUTE:
	        return self::ACTIONNAME_COMPUTE;
            break;
   
        case self::IGNORE:
	        return self::ACTIONNAME_IGNORE;
            break;
   
        case self::ABORT:
	        return self::ACTIONNAME_ABORT;
            break;
   
	    default:
            phpCR::loadException('IllegalArgument');
            throw new IllegalArgumentException("unknown on-version action: " + action);
            break;
        }
    }
    
    
   /**
    * Returns the numeric constant value of the on-version action with the
    * specified name.
    *
    * @param string
    *   The name of the on-version action
    * @return int
    *   The numeric constant value
    *
    * @throws {@link IllegalArgumentException}
    *   If $name is not a valid on-version action name.
    */
    static public function valueFromName($name) 
    {
        switch ($name) {
        case self::ACTIONNAME_COPY :
            return self::COPY;
            break;
        
        case self::ACTIONNAME_VERSION :
            return self::VERSION;
            break;
        
        case self::ACTIONNAME_INITIALIZE :
           return self::INITIALIZE;
           break;
        
        case self::ACTIONNAME_COMPUTE :
           return self::COMPUTE;
           break;
            
        case self::ACTIONNAME_IGNORE :
           return self::IGNORE;
           break;
        
        case self::ACTIONNAME_ABORT :
           return self::ABORT;
           break;
        
        default :
           phpCR::loadException('IllegalArgument');
           throw new IllegalArgumentException("unknown on-version action: " + name);
           break;
        }
    }
}

